package com.ln.drools.utils;

import com.ln.drools.kie.L2RKBase;
import com.ln.drools.kie.L2RRule;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.QNameMap;
import com.thoughtworks.xstream.io.xml.StandardStaxDriver;
import com.thoughtworks.xstream.io.xml.StaxDriver;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Message;
import org.kie.api.builder.Results;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.rule.AgendaFilter;


public class KieUtils {
    private static KieContainer kieContainer;

    public static KieContainer getKieContainer() {
        return kieContainer;
    }

    public static void setKieContainer(KieContainer newKieContainer ) {
        kieContainer = kieContainer;
    }

    public static String createKModuleXML(L2RKBase... obj){
        QNameMap qmap = new QNameMap();
        qmap.setDefaultNamespace("http://www.drools.org/xsd/kmodule");
        StaxDriver staxDriver = new StandardStaxDriver(qmap);
        XStream xstream = new XStream(staxDriver);
        xstream.autodetectAnnotations(true);
        xstream.processAnnotations(obj.getClass()); // 识别obj类中的注解
        xstream.alias("kmodule", obj.getClass());
        xstream.alias("kbase", L2RKBase.class);
        return xstream.toXML(obj);
    }

    /**
     * 构建规则过滤器
     * @param name
     * @return
     */
    public static AgendaFilter ruleNameFiler(String name){
        return match -> match.getRule().getName().equals(name);
    }

    /**
     * 重新加载规则
     * @param kmoduleXML
     * @param rules
     * @return
     */
    public static KieContainer reloadKModuleXML(String kmoduleXML, L2RRule... rules){
        KieServices kieServices = KieServices.Factory.get();
        KieFileSystem kfs = kieServices.newKieFileSystem();
        kfs.writeKModuleXML(kmoduleXML);
        for (L2RRule rule: rules) {
            _GivenContent r = loadRule(rule);
            kfs.write(r.path, r.content);
        }

        KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
        Results results = kieBuilder.getResults();
        if (results.hasMessages(Message.Level.ERROR)) {
            System.out.println(results.getMessages());
            throw new IllegalStateException("### errors ###");
        }
        System.out.println("reloadKModuleXML新规则重载成功");
        return kieServices.newKieContainer(getKieServices().getRepository().getDefaultReleaseId());
    }

    /**
     * 规则加载
     * @param rule
     * @return
     */
    private static _GivenContent loadRule(L2RRule rule){
        String packages = rule.getPackages();
        String content = rule.getContent();
        String name = rule.getName();
        final String path = "src/main/resources/"+packages+"/"+name+".drl";
        return new _GivenContent(path,content);
    }

    private static class _GivenContent{
        public _GivenContent(String path, String content) {
            this.path = path;
            this.content = content;
        }

        private  String path;
        private String content;

        public String getPath() {
            return path;
        }

        public void setPath(String path) {
            this.path = path;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }

    private static KieServices getKieServices() {
        return KieServices.Factory.get();
    }

}
